package com.tan.simpleweather.logic

import androidx.lifecycle.liveData
import com.tan.simpleweather.logic.dao.PlaceDao
import com.tan.simpleweather.logic.model.Place
import com.tan.simpleweather.logic.model.RealtimeResponse
import com.tan.simpleweather.logic.model.Weather
import com.tan.simpleweather.logic.network.PlaceService
import com.tan.simpleweather.logic.network.SimpleWeatherNetwork
import com.tan.simpleweather.utils.Constant
import com.tan.simpleweather.utils.MMKVUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlin.coroutines.CoroutineContext

/**

@author： TanJun
@date： 2021/11/12 11:48
@description： 操作库
@modifiedBy：
@version: 1.0
 */
object Repository {

    fun searchPlaces(query: String) = fire(Dispatchers.IO){
        val placeResponse = SimpleWeatherNetwork.searchPlace(query)
        if (placeResponse.status == "ok") {
            val places = placeResponse.places
            Result.success(places)
        } else {
            Result.failure(RuntimeException("response status is ${placeResponse.status}"))
        }
    }

    fun refreshWeather(lng: String, lat: String, placeName: String) = fire(Dispatchers.IO){
        coroutineScope {
            val deferredRealtime = async {
                SimpleWeatherNetwork.getRealtimeWeather(lng, lat)
            }

            val deferredDaily = async {
                SimpleWeatherNetwork.getDailyWeather(lng, lat)
            }

            val realtimeResponse = deferredRealtime.await()
            val dailyResponse = deferredDaily.await()

            if (realtimeResponse.status == "ok" && dailyResponse.status == "ok"){
                val weather = Weather(realtimeResponse.result.realtime, dailyResponse.result.daily)
                Result.success(weather)
            }else {
                Result.failure(RuntimeException("realtime response status is ${realtimeResponse.status}" +
                        "daily response status is ${dailyResponse.status}"))
            }
        }
    }

    fun saveplace(place: Place) = PlaceDao.savePlace(place)

    fun getSavedPlace() = PlaceDao.getSavedPlace()

    fun isPlaceSaved() = PlaceDao.isPlaceSaved()

    private fun <T> fire(context: CoroutineContext, block: suspend () -> Result<T>) =
        liveData<Result<T>>(context) {
            val result = try {
                block()
            }catch (e: Exception){
                Result.failure<T>(e)
            }
            emit(result)
        }

}